package com.ybox.crawler.service;
import com.ybox.common.core.exception.ServiceException;
import com.ybox.common.core.utils.UrlSpiltUtils;
import com.ybox.common.core.utils.uuid.IdUtils;
import com.ybox.crawler.domain.Article;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;


public class HtmlUtil {


    public static void main(String[] args) throws Exception {
    	// 这里的article类是业务需要，HTML保存在content字段中
        Article html = getHtml("https://mp.weixin.qq.com/s/3EMA20_WVsbZXPr_4spO4w");
        byte bytes[] = new byte[512];
        bytes = html.getResultHtml().getBytes();
        save2File("D:/java/test.html",bytes);
    }


    /**
     * 获取html
     * @param requestUrl
     * @return
     * @throws IOException
     * @throws IndexOutOfBoundsException
     * @throws ServiceException
     */
    public static Article getHtml(String requestUrl) throws IOException, IndexOutOfBoundsException, ServiceException {
        String startHtml = "<html><head>";
        String endHtml = "</body></html>";
   		// 将微信公众号的css样式提前保存在服务器当中
   		// 这样HTML中就不用保存几万行的css样式了。。。。。
        String css = "<link  href=\"./css/wechat.css\" rel=\"stylesheet\" type=\"text/css\"/>";
        String endHead = "</head><body id=\"activity-detail\" class=\"zh_CN mm_appmsg  appmsg_skin_default appmsg_style_default \"><div id=\"js_article\" class=\"rich_media\">  <div id=\"js_top_ad_area\" class=\"top_banner\"></div><div class=\"rich_media_inner\"><div id=\"page-content\" class=\"rich_media_area_primary\"> <div class=\"rich_media_area_primary_inner\">";


        // Document doc = Jsoup.parse(new URL(requestUrl),2000);

        Connection connect = Jsoup.connect(requestUrl);
        Map<String, String> header = new HashMap<String, String>();
        header.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.51");
        Connection data = connect.headers(header);
        Document doc = data.get();



        byte bytes[] = new byte[512];
        bytes = doc.toString().getBytes();
        save2File("D:/java/doc.html",bytes);

        Elements meta = doc.select("meta");
        // if (!meta.get(16).attr("content").equals("微信公众平台")){
        //     throw new ServiceException();
        // }

        // 因为公众号HTML格式比较固定，所以可以写死
        String viewPort = meta.get(4).toString();
        String charset = meta.get(1).toString();
        Elements elements = doc.select("img");
        HashMap<String,String> map= new HashMap<>(32);
        String path = null;
        for (Element elements1: elements){
            String a = elements1.attr("data-src");
            if (a != null && !"".equals(a)){
                if (map.get(a) == null || "".equals(map.get(a))){
                    try {
                    	// 下载图片
                        path = download(a, UrlSpiltUtils.getUrlMap(a).get("wx_fmt"));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    map.put(a,path);
                }
            }
        }
        Elements title = doc.getElementsByClass("rich_media_title");
        Elements element = doc.getElementsByClass("rich_media_content");
        Elements author = doc.getElementsByClass("rich_media_meta_list");
        String authorString = author.toString();
        // 将日期删除掉
        // authorString = authorString.replaceFirst("(<em)(.*?)(</em>)","");
        String html = element.toString();
        // 不知道为啥解析出来的HTML visible是hidden，所以这里替换一下
        html = html.replaceFirst("hidden","visible");
        for (Map.Entry<String, String> entry: map.entrySet()){
            html = html.replace(entry.getKey(), entry.getValue());
        }
        html = html.replace("data-src", "src");
        String resultHtml = startHtml + css + charset + viewPort + endHead + title.toString() + authorString + html + endHtml;
        String authors = meta.get(11).attr("content");
        String titles = meta.get(12).attr("content");
        String img = meta.get(14).attr("content");
        String description = meta.get(10).attr("content");
        String source = doc.getElementById("js_name").text();
        Article article = new Article(titles,authors,requestUrl,resultHtml,img,source,description);
        return article;
    }

    /**
     * 获取html图片
     * @param urlString
     * @param suffix
     * @return
     * @throws Exception
     */
    public static String download(String urlString, String suffix) throws Exception {
        // 获取URL并构造URL
        URL url = new URL(urlString);
        // 打开URL连接
        URLConnection con = url.openConnection();
        // 定义输入流
        InputStream is = con.getInputStream();
        // 定义1K的数据缓冲
        byte[] bs = new byte[1024];
        // 读取到的数据长度
        int len;
        /**
         *
         * 设置输出的文件流并设置下载路径及下载图片名称
         */
        String id = IdUtils.fastUUID();
        String filename = "D:\\java\\img\\" + id + "." + suffix;
        File file = new File(filename);
        FileOutputStream os = new FileOutputStream(file, true);
        // 开始读取
        while ((len = is.read(bs)) != -1) {
            os.write(bs, 0, len);
        }
        // 下载完毕，关闭所有链接
        os.close();
        is.close();
        String finalName = "./img/"+ id + "." + suffix;
        return finalName;
    }

    /**
     * 保存到文件
     * @param path  文件名称
     * @param bytes 字节流
     * @throws IOException
     */
    public static void save2File(String path,byte[] bytes) throws IOException {
        File txt=new File(path);
        if(!txt.exists()){
            txt.createNewFile();
        }
        FileOutputStream fileOutputStream = new FileOutputStream(txt);
        fileOutputStream.write(bytes);
        fileOutputStream.close();
    }
}


